<!DOCTYPE html>
<html>

<head>
    <title>Customize your own components </title>
    <script type="text/javascript" src="https://unpkg.com/dat.gui@0.7.6/build/dat.gui.min.js"></script>
    <link type="text/css" rel="stylesheet" href="https://unpkg.com/maptalks/dist/maptalks.css">
    <script type="text/javascript" src="https://unpkg.com/maptalks/dist/maptalks.js"></script>
    <script type="text/javascript" src="https://unpkg.com/three@0.138.0/build/three.min.js"></script>
    <script type="text/javascript" src="https://unpkg.com/maptalks.three@latest/dist/maptalks.three.js"></script>
    <style>
        html,
        body {
            margin: 0px;
            height: 100%;
            width: 100%;
        }

        #map {
            width: 100%;
            height: 100%;
            /* background-color: #000; */
        }
    </style>
</head>

<body>
    <div id="map"></div>
    <script>

        var map = new maptalks.Map("map", {
            center: [13.416935229170008, 52.529564137540376],
            zoom: 16,
            pitch: 70,
            bearing: 0,

            centerCross: true,
            doubleClickZoom: false,
            // baseLayer: new maptalks.TileLayer('tile', {
            //     urlTemplate: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
            //     subdomains: ['a', 'b', 'c', 'd'],
            //     attribution: '&copy; <a href="http://osm.org">OpenStreetMap</a> contributors, &copy; <a href="https://carto.com/">CARTO</a>'
            // })
        });


        var threeLayer = new maptalks.ThreeLayer('t', {
            forceRenderOnMoving: true,
            forceRenderOnRotating: true,
            // animation: true
        });


        threeLayer.prepareToDraw = function (gl, scene, camera) {
            var light = new THREE.DirectionalLight(0xffffff);
            light.position.set(0, -10, 10).normalize();
            scene.add(light);
            scene.add(new THREE.AmbientLight(0xffffff, 0.2));
            addTube();
            threeLayer.config('animation', true);

        };
        threeLayer.addTo(map);

        function addTube() {
            const coordinates = [
                [120.543189862389, 31.35322014824814],
                [120.54391551057267, 31.35371261270089],
                [120.54506885867931, 31.354451304544426],
                [120.54587139673674, 31.35501763102789],
                [120.54707760663155, 31.355752208849054],
                [120.54825017720657, 31.356441639795918],
                [120.54965341740296, 31.357237762100084],
                [120.55118160364418, 31.35791076744991],
                [120.55261854668379, 31.358306813092582],
                [120.55456885954129, 31.35892438695859],
                [120.55632947631534, 31.359855802165697],
                [120.55739651678448, 31.360529047629626],
                [120.5583272131937, 31.361237721856668],
                [120.55895558146995, 31.36169835723942],
                [120.55950095770982, 31.361779347842656],
                [120.55989220588185, 31.36172872872382],
                [120.56026567004596, 31.361506004277174],
                [120.56086439830915, 31.36083276580959],
                [120.56180695072362, 31.359830492091845],
                [120.56218041488785, 31.359309103054073],
                [120.56241753499216, 31.3585295451185],
                [120.56237028513135, 31.357949524158727],
                [120.5621203930416, 31.357165719008975],
                [120.56187530656894, 31.35647218963217],
                [120.56165424818187, 31.355721202348974],
                [120.56164944256477, 31.355355965928624],
                [120.56182244478077, 31.35513436111691],
                [120.56208675372181, 31.354957897652554],
                [120.56249523117617, 31.354933274817228],
                [120.56287968054517, 31.355052285128153],
                [120.56336024225618, 31.355191814266362],
                [120.56383599835021, 31.355323135619102],
                [120.56411823174483, 31.35531370115811],
                [120.56451108319175, 31.355280752400773],
                [120.56493901066062, 31.355160938640353],
                [120.56587203284698, 31.35481347787183],
                [120.56675594860246, 31.354516937062584],
                [120.56843258245613, 31.353986755709315],
                [120.5700145110502, 31.35345956676693],
                [120.57178585016345, 31.352935370285905],
                [120.57333270273546, 31.352519006427343],
                [120.57448319625848, 31.35221646750327],
                [120.57551793890877, 31.351985818362692],
                [120.57763653064012, 31.351494563762202],
                [120.57919390601887, 31.351198012486947],
                [120.5809512147232, 31.350868509973196],
                [120.58295054797964, 31.35057195672377],
                [120.58502354088239, 31.350356281045975],
                [120.58627224726706, 31.350224478999365],
                [120.5874823700276, 31.350122631836854],
                [120.59152584231651, 31.349856304834162],
                [120.59430413211135, 31.349902525810847],
                [120.59755148381964, 31.349917932798093],
                [120.60048312077856, 31.3501798511941],
                [120.60473173926357, 31.350534210215955],
                [120.60818656066442, 31.350811533736504],
                [120.61173158627935, 31.350981008818707],
                [120.6170265736481, 31.35100411903349],
                [120.62201486668891, 31.350826940574763],
                [120.62405348192806, 31.35069598236899],
                [120.62905561628952, 31.350032419603707],
                [120.62990839532642, 31.34993531589643],
                [120.63024516959456, 31.34983613848371],
                [120.63079647383688, 31.349739949917847],
                [120.63147819413666, 31.349577947900315],
                [120.63169753023317, 31.349400757874122],
                [120.63182201828783, 31.349142566095594],
                [120.63175088225648, 31.34888943621283],
                [120.6315908261862, 31.348656556118982],
                [120.63120550601684, 31.34852999060874],
                [120.63087946587348, 31.34858061683329],
                [120.63070755379783, 31.348707182275376],
                [120.6305178577145, 31.348975500449427],
                [120.63038744165715, 31.349532384782577],
                [120.63034594563885, 31.350043702948568],
                [120.63042300967277, 31.350641081047087],
                [120.63066012977697, 31.351096705859646],
                [120.63095060190471, 31.351552328464862],
                [120.63118772200892, 31.351921887401176],
                [120.63168515539405, 31.35219880544568],
                [120.63248920420028, 31.352608017684105],
                [120.63305772355818, 31.35296867784163],
                [120.63374806849276, 31.353377886729987],
                [120.63403232817177, 31.35341950109344],
                [120.63426785761999, 31.35342643681892],
                [120.63443841342746, 31.353502729765154],
                [120.63498256767002, 31.35356515122058],
                [120.63552415947902, 31.353532455415092],
                [120.63596182529568, 31.35347320158391],
                [120.63661298663283, 31.35320883788225],
                [120.63707733938963, 31.3529216833642],
                [120.6373708957301, 31.352620853881007],
                [120.63744561916224, 31.35236104582563],
                [120.63738157050614, 31.352114911216376],
                [120.63717341237384, 31.351914356613946],
                [120.63692255513729, 31.35184598562907],
                [120.63660764924475, 31.351841427561652],
                [120.63636746678435, 31.35201463396865],
                [120.63623403208419, 31.352383836034647],
                [120.63633544245636, 31.352689224302623],
                [120.63650090148462, 31.3529216833642],
                [120.63683181954116, 31.353199721879236],
                [120.63742426961016, 31.35367375286191],
                [120.63899989912761, 31.35481832702638],
                [120.64019378977923, 31.355581242410636],
                [120.64162320987919, 31.3566631845234],
                [120.64244421131548, 31.357355036087455],
                [120.64279521271169, 31.357767168817503],
                [120.64328515216039, 31.35848527456139],
                [120.64376046655104, 31.359652965234176],
                [120.64456769613616, 31.363272225986208],
                [120.64494602107004, 31.36555252186676],
                [120.64581813599784, 31.36849036625327],
                [120.6465155185075, 31.370868523138512]
            ].map(c => {
                c.push(Math.random() * 50 - 25);
                return c;
            });
            const lineStirng = new maptalks.LineString(coordinates);
            const tube = new Tube(lineStirng, {}, new THREE.MeshLambertMaterial({ color: 'red' }), threeLayer);
            threeLayer.addMesh(tube);
            map.setCenter(lineStirng.getCenter());
        }





        //default values
        var OPTIONS = {
            radius: 5,
            altitude: 0
        };

        /**
         * custom Tube component
         * 
         * you can customize your own components
         * */

        class Tube extends maptalks.BaseObject {
            constructor(lineString, options, material, layer) {
                const center = lineString.getCenter();
                options = maptalks.Util.extend({}, OPTIONS, options, { layer, lineString, coordinates: center });
                super();
                //Initialize internal configuration
                // https://github.com/maptalks/maptalks.three/blob/1e45f5238f500225ada1deb09b8bab18c1b52cf2/src/BaseObject.js#L135
                this._initOptions(options);
                const { altitude, radius } = options;
                const centerPt = layer.coordinateToVector3(center);
                const pts = lineString.getCoordinates().map(c => {
                    const pt = layer.coordinateToVector3(c);
                    pt.sub(centerPt);
                    const altitude = c.z;
                    if (altitude) {
                        pt.z = layer.altitudeToVector3(altitude).x;
                    }
                    return pt;
                })
                const curve = new THREE.CatmullRomCurve3(pts);

                // const points = curve.getPoints(pts.length);
                //generate geometry
                const r = layer.distanceToVector3(radius, radius).x;
                const geometry = new THREE.TubeGeometry(curve, pts.length * 10, r, 10, false);

                //Initialize internal object3d
                // https://github.com/maptalks/maptalks.three/blob/1e45f5238f500225ada1deb09b8bab18c1b52cf2/src/BaseObject.js#L140
                this._createMesh(geometry, material);

                //set object3d position
                const z = layer.altitudeToVector3(altitude, altitude).x;
                centerPt.z = z;
                this.getObject3d().position.copy(centerPt);
                // this.getObject3d().rotation.x = -Math.PI;
            }



        }






    </script>
</body>

</html>